package mapData;

import java.util.ArrayList;

public class AbstractedMap 
{
	private Map refMap;
	private int width,height; // using 1 cluster per unit
	private int clusterWidth, clusterHeight;
	private CoordCluster clusterTable[][];
	private ArrayList<Coord> globalTransitionList = new ArrayList<Coord>(20);
	
	public AbstractedMap(Map ref, int partitionsW, int partitionsH)
	{
		refMap = ref;
		width = partitionsW;
		height = partitionsH;
		clusterTable = new CoordCluster[width][height];
		createPartitions();
		
	}

	public int getWidth() 
	{
		return width;
	}

	public void setWidth(int width) 
	{
		this.width = width;
		createPartitions(); //update abstracted map
	}

	public int getHeight() 
	{
		return height;
	}

	public void setHeight(int height) 
	{
		this.height = height;
		createPartitions(); //update abstracted map
	}
	
	public int getClusterWidth()
	{
		return clusterWidth;
	}
	
	public int getClusterHeight()
	{
		return clusterHeight;
	}
	
	public void buildTransitionList()
	{
		for(int i = 0; i < this.width -1; i++)
		{
			for(int j = 0; j < this.height -1; j++)
			{
				int tLX = clusterTable[i][j].getTopLeft().getX();
				int tLY = clusterTable[i][j].getTopLeft().getY();
				int bRX = clusterTable[i][j].getBottomRight().getX();
				int bRY = clusterTable[i][j].getBottomRight().getY();
				//evaluate top border
				for(int tX = tLX; tX < bRX; tX++)
				{
					
				}
			}
		}
	}
	
	/**
	 * partitions the map into width*height number of sections, each with 
	 * dimensions mapWidth/width * mapHeight/height
	 */
	private void createPartitions()
	{
		clusterWidth = refMap.getWidth()/width; //width of each cluster
		clusterHeight = refMap.getHeight()/height; //height of each cluster
		
		for(int i = 0; i < width; i++)
		{
			for(int j = 0; j < height; j++)
			{
				Coord topLeft = new Coord(clusterWidth*i, clusterHeight*j); 
				Coord bottomRight = new Coord(clusterWidth*(i+1)-1, clusterHeight*(j+1)-1);
				
				//validity checks probably not needed as invalid Coords won't be considered for pathfinding
				clusterTable[i][j] = new CoordCluster(i,j, topLeft, bottomRight, 1);				
			}
			
		}
		
	}
	
	/**
	 * Returns a reference to cluster based on array index in Abstract map
	 * @param x
	 * @param y
	 * @return Returns null if cluster does not exist, else return a reference to the cluster
	 */
	public CoordCluster getCluster(int i, int j)
	{
		if(i >= 0 && j >=0 && i < width && j < height)
		{
			CoordCluster found = clusterTable[i][j];
			return found; 
		}
		else
		{
			System.out.println("Cluster does not exist");
			return null;
		}
	}
	
	/**
	 * Returns a reference to the cluster containing pos.
	 * If the cluster or Coord does not exist an the map, it returns null
	 * @param pos
	 * @return
	 */
	public CoordCluster getContainingCluster(Coord pos)
	{
		if(pos.isValid())
			return getCluster(pos.getX()/clusterWidth, pos.getY()/clusterHeight);
		else
			return null;
	}
	
	
	
	
	/**
	 * Returns an Arraylist of all clusters from left to right, top to bottom
	 * @returns 
	 */
	public ArrayList<CoordCluster> listAll()
	{
		ArrayList<CoordCluster> list = new ArrayList<CoordCluster>(0);
		int i = 0;
		int j = 0;
		while(true)
		{
			list.add(clusterTable[i][j]);
			i++;
			
			
			if(i == this.width)
			{
				i = 0;
				j++;
			}
			
			if(i==0 && j == this.height) break;
			
		}
		
		return list;
		
	}
	 

}
